package br.com.afi.pattern.interpreter;

import java.util.Map;
import java.util.Stack;

import br.com.afi.pattern.interpreter.expression.Expression;
import br.com.afi.pattern.interpreter.expression.ProgressiveResultExpression;

/**
 * Classe responsável por intepretar as expressões
 * 
 * @author André de Fontana Ignacio
 * @version 1.0
 */
public class StackEvaluator implements Evaluator{
	private Stack<Expression> expressionStack;
	
	/**
	 * Interpreta as variáveis informadas.
	 * 
	 * @param variables Variáveis 
	 * @param result Resultado
	 * @return Resultado
	 */
	public Object evaluate( Map<String,Object> variables, Object result ) 
	{
		while(!expressionStack.empty())
		{
			final Expression expression = expressionStack.pop();
			if(expression instanceof ProgressiveResultExpression)
			{
				( (ProgressiveResultExpression) expression ).setResult( result );
			}
			result = expression.interpret( variables );
		}
        return result;
    }
	
	@Override
	public Object evaluate(Map<String, Object> variables) {
		Object result = null;
		while(!expressionStack.empty())
		{
			final Expression expression = expressionStack.pop();
			result = expression.interpret( variables );
		}
        return result;
	}

	@Override
	public void setExpression( Expression expression )
	{
		if( expressionStack == null )
		{
			expressionStack = new Stack<Expression>();
		}
		expressionStack.push( expression );
	}
	
	/**
	 * Atribuí a pilha expressões a serem interpretadas
	 * 
	 * @param expressionStack Pilha de expressões
	 */
	protected void setExpressionStack( Stack<Expression> expressionStack )
	{
		this.expressionStack = expressionStack;
	}
}
